<?php
namespace payment;

use \think\Db;

/**
 * 支付宝支付类
 */
class Alipay {

    //是否沙盒环境
    public $is_sandbox = false;
    //沙盒地址
    private $sandurl = 'https://openapi.alipaydev.com/gateway.do';
    //正式地址
    private $url = 'https://openapi.alipay.com/gateway.do';
    //appid
    private $appid = '2019120969709820';
    //sand appid
    private $sandappid = '2016102000728101';
    //回调前缀
    private $notify_url;
    //商户应用私钥
    private $rsaPrivateKey = 'MIIEowIBAAKCAQEA6vn0D0WJ1rnpQz6IXSCc46Qnlv8rMuzyZznlISGcgp36PDys6pvNMhiRP5NEQg2o8dgcUt8YkoxaUPRRzwzL/VnE0bhiP7wtowkwpxNrsvmSUEJX1EmPhkPjHZ85rB5FotfNb0ToXQt0JA8Mjqwgb1Wt9JRgsbvI9nsMnG3mUNGX5P/s11ZWvegBejByZ8IQaWbQs7qu1hhuOhYNZXlmO1CGp3x0qJK816zYICuCRnXGI+hJMTLvDzRK5QY0grlchN6buqlqVS8mkhaCHNDOCjqX0WtgYebPNyrPrk6iZaX0chZCtawz3zwpng7IdYe66djMkv340ZqoQxXp5ZcqfwIDAQABAoIBACcKmsOC0VEtGJXEqRGYHpkwKCfNg9b1SZ1fIDPuCrwlFXO2vSBJ/MELFe8TP+8dp+lu993JFaMb0NHMll8piCczKCGUWjauxIJnP38zGdzl3KqbK06pXkB3vR+p2gJAEV/qLUcEkvsKsSRgn7yA2u7EtJ+Dm8FMKyrQ7Rp8pBzfNKg6e/GLKtjyrUHxbgXYP+rhxX4AuB+GW2CNncW1jXDUrkMANo6h6D6BDh0NIc1fKecHRDtv1uHnPwwzkh2hW1NEZ6jS+8q1qARn2sduItee96AsE6Y8OWjEmemOQ7jcMVaEf2bVPvJyhheT/vmwly1e77EwoExTaA5IlMBfJ0kCgYEA/lqkYjL+Zuif75Q+D9Ot7hMoEt38v3A1V7XCf8tDaam4wB/Q9GcScvC0kJ3ivuqBJKBd7DPmQXOtFjUjLWkohiNkzyK+GP8n3y4YWEwdpb2BMqGqQHq9teOvJKJIh4ObsDYFwbwfNNUnyz+VpMfIYzUeJBWsgLjxYRVs/9u5VGUCgYEA7H815egwzpxgBZB+1ZsyHWuTcGwDPVPqBpRKMEKa6U4XyPuED8mu9Xfg00vyahqBMMdu68W+aW9HhLpblFHKXgrHAfSmoXET7wPjGVoAAU1pFFUeZJF4PehlGymMVyLV57rPgCruEvWjagEK41ziI/YhlVNwg6oTyu98CGoeWxMCgYEA1Pdd9d7Oham26ClOQYAyfElL32hBDKVN9I96N/ggDKOPzkWVdl2q49RIy2F3DfVZhipEGdZmr1zEiviY6JfI129hI9HqKxHQ95wnxB6PIEvollUoMO7UUyw9ZEYAxn5aaBMDhPAXjOwAcrxddmfUj8RU5U/EbM7tRCVla2E07sUCgYAo9wAHCukpYLzhOd4+cduEbRXk61DEVry61wTixya+MuC715VQhsbfjhxLfWRILL8kC+eSv3X0HWpt+znRvzkmgQdnt1EFteiWBj5YLdbCYv5In1XcZbZGQvMAeXntvgL/WMSIlucWMaZUvkl8iKJDSGcYzpM2u0ciZ8k8S+VmMQKBgCE3SW96VT6tNhs7q8SF7zvJ7ZjZN8vGSvfONYvJ9v4fbaQhY/O7iWnQoBOfKNVnq7Bec0Eav6fmMP+V1jR9f6DXr3S1dvbbub4DzxceLz3KdZHN/g8+YWbQSN4TwDQgLUdCzE+z1oBwM9Q+zusumm2o8SakdneEkLJ0/8QCQ7iJ';

    //支付宝公钥 验签使用
    private $alipayPublicKey= 'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsM94xQdElIT1bRWCuUMYP3TBG7pdSfwJHFVYsps9l1lCaIM8riNf4dAZq3SDQpUrrEgD6OySmi+lBnO66bkzDYX/EpLx3EGzbOMpJLF1ANorbBX8RcZWvSaua8igYO7IVAXHl+3JTyEy3gWp7EDVcPC0iIQDftWav3wQmT96+C/YXddnDfhyOpMOpyrnj2cRsLWpbJBLk5nn124SAQN4N3uRdy0PRWqhNFo6EWT8rnfoYzK6mCJIxtDkRUXZ3y46jpZSpSmu5TR3cy2EGYf5zGydN5AtFGw+me1GmA+weaHNR1dEF41O17Qq9XLF4QnGC0nED6frwUHDYsQWoT908wIDAQAB';

    //沙盒应用私钥
    private $sandrsaPrivateKey = 'MIIEowIBAAKCAQEAimb56Hp8VN6QdSF8fZnyI2xFl/VDN7dB/CxHN/vKAKY77azlvza41IdOMsGNkmZ17Z5sjsIPw+2W6Ycd3l2fx3QG7xOT+MK2uxyX0AQquqxm4eLfeVj6U7Yd1quaHqfk0tcviLxwvEOGIukhJIHd4kQkqSM0B5rxbA5LJA7i7z4V3r0Cuz2kgyhhSHcPhriFPfPdnODMHfA4KUHKF8LKeUvmywh0T1SbJ97MxCyfgGk+qOkYZD64Av24PngelcbmTftngWSzbWbr48DePnMT6+8kA6WK2cGJbVVJANEZuBXixlN3GyvLXk0z3SyXqWH2isMly8M6U6J1xFy49KKuEQIDAQABAoIBADhnkU/ao1MfRXZHCGpT1Cf1l0M/1H4fdIfmL7w0JHYxSVkqzpMoJRmQbyEmWqEgms0VdJ6VnkE2UfuoclbOhzCNK8pBi1ulVz1YgNJo8FUVr/Q9NuBIj/SP0wdK9kuqFwqKYjfyvGsthbwykKxFNP1i0iIQU8MJtXxZMuxmGLxxT/BGyKbuyf24rm2c2u9Evdbd494lwolBWIC4Miioc+g4JWE27CR24rut+17ool6WD1K+Q0ZHckKCY8O6w+/WW9tj7Y2CmAqt64lUWEwlvfzRkWCxt3B8QiqnP91cL5UtPNSvutl4hPFfeuv5bLsPHjpfnwk3iDWkZ89jSCaAZgECgYEA4vJo4HLz9h4XkYpCjaPfJ4makCsRY8/uiXu3qTfaQMsTjoaTG+9Y2NOmC3H2hE5wuRijGOyvavCaI+7IxpQI6cCPFjSqpHoDndyVboU30rg39LGH9vajdQpQQBEFbnm0NlIkUUS+9rlvslAPXB5jMNLYFYPcwgtBiQ9qTFVSLvECgYEAnB6/TVSSP5SIXG9qW+j3n8kmgXX5OphAXoAjqxHIHd1Mz+krhRCo1GQRbaWjI9uUOjgvA3CEg1Trmp3uFsbNbjiF7b0FTaHyRPVaSlkHUrLN8mNFelULjjq7F8mKzyn6LVTibRHdzXJltm0WjgjYSWO1LwBrzLkW+7f0qXf2sSECgYB/QejXOv5b2wHiRYIORH6kf/+gqdXFf1pF047oH36N6JHd0M560pqicwPf1RajmAyTbiI+nrG6qJH2ZjZFS8s3sBdMH1o0goq2oXNVlvP3f/84gbg5HpIH1jGryx+dlDceYq8ktwTR+qeMeGI0iIGcZg5u+hL26DLmdTNo/ErqMQKBgQCVPYtQaC0aHGoyOsuoqs60b3ygu18RlWPLMqFmMixj6B46jkJtBJzv0+0ZLQMEDy7mbLj8h74VMcO73YcxPMA6wku9FTmRmeNX6ldyxSKL+qOHN0C+jbfrMdeSCLbqDM28Me31p+OpNtdmiWfLRUdE+MzF7pgebz06SgLXUfeAIQKBgHfPHrBu5dNwZWffHDAUEagdAO7hrzlrkNVB7EdPQUuj2M+rRa/guyoArouoZIfjJ99MUsxD/A+6CuFmOdybBtuQEze9bDtrRe1m7E2EEuUvLa64vyRJS4CmM8Wu8M8w6lcRJ6aNGIWEm8MBLj0JP4T68AyJ0Di0LLUMX3zezMNX';

    private $sandalipayPublicKey = 'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA7677HQdw9HGpKrMk6e2F8gIIZXvnvMsizIL8NTKgNyuuuLdzocJmKfjlImoYHmSNUiG/NIUgy6fG3ISRUg8Df9p3YdLEEJbfHnv0Boc9cntPnUvh6GDE8HjcNAvvpPHv8L6MggSjDadmQ/hHACiLfOxD1XFzFbx38nyoxwMiX7S7i7INuYdQl4jOKHRgZHU0dMoE7uCZeOrUiw4cwyOS/OtNd+D0GgAmpmJzn00wvdLEnF9X78zvRjKMbtJKO2Fy2UOCi35weSBMYEQGrUyOBUBIhyFfe6bj4iTpxxlKhwLGQNAdp5OodK95QznRfgGzHyzRR3N1X7Lj1Ow+LBPnhQIDAQAB';


    public function __construct(){

        if(!is_dir('static/logs')){
            mkdir('static/logs', 0777);
        }
    }

    /**
     * @author     mselect <445712421@qq.com>
     *
     * @DateTime 2018-11-16 10:57:51
     * 当面付
     */
    public function pay($order_id){}

    /**
     * @author     mselect <445712421@qq.com>
     *
     * @DateTime 2018-11-19 15:03:28
     * PC网站支付
     */
    public function pagepay($order_id){}


    /**
     * @author     mselect <445712421@qq.com>
     *
     * @DateTime 2018-12-21 16:10:11
     * app支付
     *
     * @param <intval>  order_id  订单ID
     */
    public function apppay($orderid){

        //支付宝APP支付， 支付接口组合数据
        $time = time();
        $order = Db::name('order')->where('id', $orderid)->find();
        $notify_url =  $this->notify_url . '回调地址';
        if($this->is_sandbox){
            $this->url = $this->sandurl;
            $this->appid = $this->sandappid;
            $this->rsaPrivateKey = $this->sandrsaPrivateKey;
            $this->alipayPublicKey = $this->sandalipayPublicKey;
        }

        //业务参数
        $biz_content = array(
            'subject' => 'XXXX',
            'out_trade_no' => $order['order_unique'],
            'total_amount' => $order['real_total_money'],
            'product_code' => 'QUICK_MSECURITY_PAY',
        );

        import('AopClient', EXTEND_PATH . 'payment/alipay/aop');
        import('AlipayTradeAppPayRequest', EXTEND_PATH . 'payment/alipay/aop/request');
        $aop = new \AopClient;
        $aop->gatewayUrl = $this->url;
        $aop->appId = $this->appid;

        $aop->rsaPrivateKey = $this->rsaPrivateKey;
        $aop->format = "json";
        $aop->charset = "UTF-8";
        $aop->signType = "RSA2";
        $aop->alipayrsaPublicKey =$this->alipayPublicKey;
        //实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称：alipay.trade.app.pay
        $request = new \AlipayTradeAppPayRequest();
        //SDK已经封装掉了公共参数，这里只需要传入业务参数
        $request->setNotifyUrl($notify_url);
        $request->setBizContent(json_encode($biz_content));
        //这里和普通的接口调用不同，使用的是sdkExecute
        $response = $aop->sdkExecute($request);
        //htmlspecialchars是为了输出到页面时防止被浏览器将关键参数html转义，实际打印到日志以及http传输不会有这个问题
        $return = $response;//就是orderString 可以直接给客户端请求，无需再做处理。
        return $return;
    }


    /**
     * @author     mselect <445712421@qq.com>
     *
     * @DateTime 2018-11-16 13:36:17 { function_description }
     * 支付宝支付通知
     *
     * @param      <type>  $data   异步通知返回的所有数据
     */
    public function notify($data){
        if($this->is_sandbox){
            $this->alipayPublicKey = $this->sandalipayPublicKey;
        }

        import('AopClient', EXTEND_PATH . 'payment/alipay/aop');
        $aop = new \AopClient;
        $aop->alipayrsaPublicKey = $this->alipayPublicKey;
        $flag = $aop->rsaCheckV1($data, NULL, "RSA2");

        $order = Db::name("order")->where('order_unique', $data['out_trade_no'])->where('status', -1)->find();
        if($order['real_total_money'] != $data['total_amount']){
            file_put_contents('static/logs/alipaynotify.log', '异步返回订单金额不正确， 时间：' . date("Y-m-d H:i:s") . "\r\n", FILE_APPEND);exit;
        }
        $rst = $this->orderquery($order, 'TRADE_SUCCESS');
        if($rst){
            $time = time();
            Db::startTrans();
            try {
                //TODO... 数据库操作
                Db::commit();
            }catch(\Exception $e){
                Db::rollback();

                file_put_contents('static/logs/alipaynotify.log', '修改数据库失败，失败信息:' . $e->getMessage() . "，记录时间：" . date('Y-m-d H:i:s') . "\r\n", FILE_APPEND);exit;
            }
            echo 'success';exit;
        }else {
            file_put_contents('static/log/alipaynotify.log', "查询订单状态错误时间：" .date("Y-m-d H:i:s").  "\r\n", FILE_APPEND);
            exit;
        }

    }


    /**
     * @author     mselect <445712421@qq.com>
     *
     * @DateTime 2018-11-16 13:39:15
     * 支付查询接口
     *
     * @param  order  订单数据
     * @param  status  要验证的状态  WAIT_BUYER_PAY-交易创建等待买家付款 TRADE_CLOSED-未付款交易超时关闭或支付完成后全额退款  TRADE_SUCCESS-交易支付成功 TRADE_FINISHED-交易结束不可退款
     */
    public function orderquery($order , $status){

        //是否沙盒环境
        if($this->is_sandbox){
            $this->url = $this->sandurl;
            $this->appid = $this->sandappid;
            $this->rsaPrivateKey = $this->sandrsaPrivateKey;
            $this->alipayPublicKey = $this->sandalipayPublicKey;
        }
        $biz_content = [
            'out_trade_no' => $order['order_unique'],
            'trade_no' => $order['trade_no'],
        ];
        import('AopClient', EXTEND_PATH . 'payment/alipay/aop');
        import('AlipayTradeQueryRequest', EXTEND_PATH . 'payment/alipay/aop/request');

        $aop = new \AopClient;

        $aop->gatewayUrl = $this->url; //'https://openapi.alipay.com/gateway.do';
        $aop->appId = $this->appid; // 'your app_id';
        $aop->rsaPrivateKey = $this->rsaPrivateKey; //'请填写开发者私钥去头去尾去回车，一行字符串';
        $aop->alipayrsaPublicKey= $this->alipayPublicKey; //'请填写支付宝公钥，一行字符串';
        $aop->apiVersion = '1.0';
        $aop->signType = 'RSA2';
        $aop->postCharset='UTF-8';
        $aop->format='json';
        $request = new \AlipayTradeQueryRequest;
        $request->setBizContent(json_encode($biz_content));
        $result = $aop->execute ( $request);

        $responseNode = str_replace(".", "_", $request->getApiMethodName()) . "_response";
        $resultCode = $result->$responseNode->code;
        if(!empty($resultCode)&&$resultCode == 10000){
            return true;
        } else {
            return false;
        }
    }


    /**
     * @author     mselect <445712421@qq.com>
     *
     * @DateTime 2018-12-26 15:39:57
     * 交易关闭接口
     *
     * @param <intval> order_id 订单ID
     */
    public function trade_close($order_id){

        $order = Db::name('order')->where('id', $order_id)->find();
        if($this->is_sandbox){
            $this->url = $this->sandurl;
            $this->appid = $this->sandappid;
            $this->rsaPrivateKey = $this->sandrsaPrivateKey;
            $this->alipayPublicKey = $this->sandalipayPublicKey;
        }
        //请求参数
        $biz_content = array(
            'out_trade_no' => $order['order_unique'],
        );

        import('AopClient', EXTEND_PATH . 'payment/alipay/aop');
        import('AlipayTradeCloseRequest', EXTEND_PATH . 'payment/alipay/aop/request');

        $aop = new \AopClient ();
        $aop->gatewayUrl = $this->url;
        $aop->appId = $this->appid;
        $aop->rsaPrivateKey = $this->rsaPrivateKey; //'请填写开发者私钥去头去尾去回车，一行字符串';
        $aop->alipayrsaPublicKey= $this->alipayPublicKey; //'请填写支付宝公钥，一行字符串';
        $aop->apiVersion = '1.0';
        $aop->signType = 'RSA2';
        $aop->postCharset='UTF-8';
        $aop->format='json';
        $request = new \AlipayTradeCloseRequest;
        $request->setBizContent(json_encode($biz_content));
        $result = $aop->execute ( $request);

        $responseNode = str_replace(".", "_", $request->getApiMethodName()) . "_response";
        $resultCode = $result->$responseNode->code;

        if( (!empty($resultCode)&&$resultCode == 10000 ) || (!empty($resultCode)&&$resultCode == 40004)  ){
            return true;
        } else {
            file_put_contents('static/logs/alipaytradeclose.log', '关闭订单失败, 失败码：'. $result->$responseNode->code . ", 失败原因：". $result->$responseNode->msg . "\r\n", FILE_APPEND);
            return false;
        }
    }



}
